﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace TongCheng.API.OpenAPI.Util
{
    public class Tools
    {
        /// <summary>
        /// string型转换为bool型
        /// </summary>
        /// <param name="strValue">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的bool类型结果</returns>
        public static bool StrToBool(object strValue, bool defValue)
        {
            bool l = false;
            if (strValue == null) return defValue;
            if (bool.TryParse(strValue.ToString(), out l))
            {
                return l;
            }
            else
                return defValue;
        }

        /// <summary>
        /// 将对象转换为Int32类型
        /// </summary>
        /// <param name="strValue">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的int类型结果</returns>
        public static int StrToInt(object strValue, int defValue)
        {
            int l = 0;
            if (strValue == null) return defValue;
            if (int.TryParse(strValue.ToString(), out l))
            {
                return l;
            }
            else
                return defValue;
        }


        /// <summary>
        /// string型转换为float型
        /// </summary>
        /// <param name="strValue">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的int类型结果</returns>
        public static double StrToDouble(object strValue, double defValue)
        {
            double l = 0;
            if (strValue == null) return defValue;
            if (double.TryParse(strValue.ToString(), out l))
            {
                return l;
            }
            else
                return defValue;
        }

        /// <summary>
        /// string型转换为float型
        /// </summary>
        /// <param name="strValue">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的int类型结果</returns>
        public static decimal StrToDecimal(object strValue, decimal defValue)
        {
            decimal l = 0;
            if (strValue == null) return defValue;
            if (decimal.TryParse(strValue.ToString(), out l))
            {
                return l;
            }
            else
                return defValue;
        }

        /// <summary>
        /// string型转换为float型
        /// </summary>
        /// <param name="strValue">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的int类型结果</returns>
        public static float StrToFloat(object strValue, float defValue)
        {
            float l = 0;
            if (strValue == null) return defValue;
            if (float.TryParse(strValue.ToString(), out l))
            {
                return l;
            }
            else
                return defValue;
        }

        /// <summary>
        /// string型转换为long型
        /// </summary>
        /// <param name="strValue">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的int类型结果</returns>
        public static long StrToLong(object strValue, long defValue)
        {
            long l = 0;
            if (strValue == null) return defValue;
            if (long.TryParse(strValue.ToString(), out l))
            {
                return l;
            }
            else
                return defValue;
        }

        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="type">对象类型</param>
        /// <param name="filepath">文件路径</param>
        /// <returns></returns>
        public static T Deserialize<T>(string filepath)
        {
            FileStream fs = null;
            try
            {
                Type type = typeof(T);
                // open the stream...
                fs = new FileStream(filepath, FileMode.Open, FileAccess.Read);
                XmlSerializer serializer = new XmlSerializer(type);
                return (T)serializer.Deserialize(fs);
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (fs != null)
                    fs.Close();
            }
        }


        /// <summary>
        /// 序列化
        /// </summary>
        /// <param name="obj">对象</param>
        /// <param name="filepath">文件路径</param>
        public static void Serialize(object obj, string filepath)
        {
            try
            {
                //如果目录不存在，则先创建目录
                string dirPath = Path.GetDirectoryName(filepath);
                if (!Directory.Exists(dirPath))
                {
                    Directory.CreateDirectory(dirPath);
                }

                TextWriter writer = new StreamWriter(filepath);
                XmlSerializer serializer = new XmlSerializer(obj.GetType());
                serializer.Serialize(writer, obj);
                writer.Close();
                writer = null;
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
        }

        #region xml操作 for xmlnode innertext
        public static string GetXmlNodeInnerText(XmlNode node, string xpath)
        {
            if (string.IsNullOrEmpty(xpath))
            {
                return node.InnerText;
            }
            return node.SelectSingleNode(xpath) == null ? "" : node.SelectSingleNode(xpath).InnerText;
        }

        public static int GetXmlNodeInnerTextToInt(XmlNode node, string xpath, int defValue)
        {
            if (string.IsNullOrEmpty(xpath))
            {
                return StrToInt(node.InnerText, defValue);
            }
            return node.SelectSingleNode(xpath) == null ? defValue : StrToInt(node.SelectSingleNode(xpath).InnerText, defValue);
        }

        public static long GetXmlNodeInnerTextToLong(XmlNode node, string xpath, long defValue)
        {
            if (string.IsNullOrEmpty(xpath))
            {
                return StrToLong(node.InnerText, defValue);
            }
            return node.SelectSingleNode(xpath) == null ? defValue : StrToLong(node.SelectSingleNode(xpath).InnerText, defValue);
        }

        public static double GetXmlNodeInnerTextToDouble(XmlNode node, string xpath, double defValue)
        {
            if (string.IsNullOrEmpty(xpath))
            {
                return StrToDouble(node.InnerText, defValue);
            }
            return node.SelectSingleNode(xpath) == null ? defValue : StrToDouble(node.SelectSingleNode(xpath).InnerText, defValue);
        }

        public static bool GetXmlNodeInnerTextToBool(XmlNode node, string xpath, bool defValue)
        {
            if (string.IsNullOrEmpty(xpath))
            {
                return StrToBool(node.InnerText, defValue);
            }
            return node.SelectSingleNode(xpath) == null ? defValue : StrToBool(node.SelectSingleNode(xpath).InnerText, defValue);
        }
        #endregion

        #region xml操作 for xmlnode attibute
        public static string GetXmlNodeAttribute(XmlNode node, string xpath, string attribute)
        {
            if (string.IsNullOrEmpty(xpath))
            {
                if (node.Attributes[attribute] != null)
                {
                    return node.Attributes[attribute].Value;
                }
                else
                    return string.Empty;
            }

            if (node.SelectSingleNode(xpath) != null
                && node.SelectSingleNode(xpath).Attributes[attribute] != null)
                return node.SelectSingleNode(xpath).Attributes[attribute].Value;
            else
                return string.Empty;
        }

        public static int GetXmlNodeAttributeToInt(XmlNode node, string xpath, string attribute, int defValue)
        {
            if (string.IsNullOrEmpty(xpath))
            {
                if (node.Attributes[attribute] != null)
                {
                    return StrToInt(node.Attributes[attribute].Value, defValue);
                }
                else
                    return defValue;
            }

            if (node.SelectSingleNode(xpath) != null
                && node.SelectSingleNode(xpath).Attributes[attribute] != null)
                return StrToInt(node.SelectSingleNode(xpath).Attributes[attribute].Value, defValue);
            else
                return defValue;
        }

        public static long GetXmlNodeAttributeToLong(XmlNode node, string xpath, string attribute, long defValue)
        {
            if (string.IsNullOrEmpty(xpath))
            {
                if (node.Attributes[attribute] != null)
                {
                    return StrToLong(node.Attributes[attribute].Value, defValue);
                }
                else
                    return defValue;
            }

            if (node.SelectSingleNode(xpath) != null
                && node.SelectSingleNode(xpath).Attributes[attribute] != null)
                return StrToLong(node.SelectSingleNode(xpath).Attributes[attribute].Value, defValue);
            else
                return defValue;
        }

        public static double GetXmlNodeAttributeToDouble(XmlNode node, string xpath, string attribute, double defValue)
        {
            if (string.IsNullOrEmpty(xpath))
            {
                if (node.Attributes[attribute] != null)
                {
                    return StrToDouble(node.Attributes[attribute].Value, defValue);
                }
                else
                    return defValue;
            }

            if (node.SelectSingleNode(xpath) != null
                && node.SelectSingleNode(xpath).Attributes[attribute] != null)
                return StrToDouble(node.SelectSingleNode(xpath).Attributes[attribute].Value, defValue);
            else
                return defValue;
        }

        public static bool GetXmlNodeAttributeToBool(XmlNode node, string xpath, string attribute, bool defValue)
        {
            if (string.IsNullOrEmpty(xpath))
            {
                if (node.Attributes[attribute] != null)
                {
                    return StrToBool(node.Attributes[attribute].Value, defValue);
                }
                else
                    return defValue;
            }
            if (node.SelectSingleNode(xpath) != null
                && node.SelectSingleNode(xpath).Attributes[attribute] != null)
                return StrToBool(node.SelectSingleNode(xpath).Attributes[attribute].Value, defValue);
            else
                return defValue;
        }
        #endregion

        #region xml操作 for XmlDocument innertext
        public static string GetXmlDocumentInnerText(XmlDocument doc, string xpath)
        {
            var node = doc.DocumentElement;
            return node.SelectSingleNode(xpath) == null ? "" : node.SelectSingleNode(xpath).InnerText;
        }

        public static int GetXmlDocumentInnerTextToInt(XmlDocument doc, string xpath, int defValue)
        {
            var node = doc.DocumentElement;
            return node.SelectSingleNode(xpath) == null ? defValue : StrToInt(node.SelectSingleNode(xpath).InnerText, defValue);
        }

        public static long GetXmlDocumentInnerTextToLong(XmlDocument doc, string xpath, long defValue)
        {
            var node = doc.DocumentElement;
            return node.SelectSingleNode(xpath) == null ? defValue : StrToLong(node.SelectSingleNode(xpath).InnerText, defValue);
        }

        public static double GetXmlDocumentInnerTextToDouble(XmlDocument doc, string xpath, double defValue)
        {
            var node = doc.DocumentElement;
            return node.SelectSingleNode(xpath) == null ? defValue : StrToDouble(node.SelectSingleNode(xpath).InnerText, defValue);
        }

        public static bool GeXmlDocumentInnerTextToBool(XmlDocument doc, string xpath, bool defValue)
        {
            var node = doc.DocumentElement;
            return node.SelectSingleNode(xpath) == null ? defValue : StrToBool(node.SelectSingleNode(xpath).InnerText, defValue);
        }
        #endregion

        #region xml操作 for XmlDocument attibute
        public static string GetXmlDocumentAttribute(XmlDocument doc, string xpath, string attribute)
        {
            var node = doc.DocumentElement;
            return GetXmlNodeAttribute(node, xpath, attribute);
        }

        public static int GetXmlDocumentAttributeToInt(XmlDocument doc, string xpath, string attribute, int defValue)
        {
            var node = doc.DocumentElement;
            return GetXmlNodeAttributeToInt(node, xpath, attribute, defValue);
        }

        public static long GetXmlDocumentAttributeToLong(XmlDocument doc, string xpath, string attribute, long defValue)
        {
            var node = doc.DocumentElement;
            return GetXmlNodeAttributeToLong(node, xpath, attribute, defValue);
        }

        public static double GetXmlDocumentAttributeToDouble(XmlDocument doc, string xpath, string attribute, double defValue)
        {
            var node = doc.DocumentElement;
            return GetXmlNodeAttributeToDouble(node, xpath, attribute, defValue);
        }

        public static bool GetXmlDocumentAttributeToBool(XmlDocument doc, string xpath, string attribute, bool defValue)
        {
            var node = doc.DocumentElement;
            return GetXmlNodeAttributeToBool(node, xpath, attribute, defValue);
        }
        #endregion
    }
}
